package com.ssy.lingxi.order.entity;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import javax.persistence.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.Set;

/**
 * 订单商品、物料信息
 * @author 万宁
 * @version 2.0.0
 * @date 2021-07-15
 */
@Entity
@Table(schema = "public", name = "ord_product", indexes = {@Index(name = "ord_product_order_id_idx", columnList = "order_id"), @Index(name = "ord_product_price_type_idx", columnList = "priceType"), @Index(name = "ord_product_product_id_idx", columnList = "productId"), @Index(name = "ord_product_sku_id_idx", columnList = "skuId"), @Index(name = "ord_product_separate_type_idx", columnList = "separateType"), @Index(name = "ord_product_relation_id_idx", columnList = "relationId")})
public class OrderProductDO implements Serializable {
    private static final long serialVersionUID = 5039196734020227415L;

    /**
     * 主键Id
     */
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "ord_product_seq")
    @SequenceGenerator(sequenceName = "ord_product_seq", name = "ord_product_seq", allocationSize = 1)
    private Long id;

    /**
     * 多对一双向关联订单
     */
    @JsonBackReference
    @ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.LAZY)
    @JoinColumn(name = "order_id")
    private OrderDO order;

    /**
     * 商品类型，定义在商品服务的 PriceTypeEnum 中
     */
    @Column
    private Integer priceType;

    /**
     * 商品Id（来自商品服务）
     */
    @Column
    private Long productId;

    /**
     * 商品skuId（来自商品服务）
     */
    @Column
    private Long skuId;

    /**
     * 渠道商品库存Id，仅用于扣减、返还渠道商品库存
     */
    @Column
    private Long stockId;

    /**
     * 商品购物车Id，仅用于下单成功后，删除购物车
     */
    @Column
    private Long cartId;

    /**
     * 商品（物料）编号
     */
    @Column(columnDefinition = "varchar(30)")
    private String productNo;

    /**
     * 商品名称
     */
    @Column(columnDefinition = "varchar(100)")
    private String name;

    /**
     * 商品品类
     */
    @Column(columnDefinition = "varchar(50)")
    private String category;

    /**
     * 商品品牌
     */
    @Column(columnDefinition = "varchar(50)")
    private String brand;

    /**
     * 商品规格
     */
    @Column(columnDefinition = "varchar(255)")
    private String spec;

    /**
     * 计价单位
     */
    @Column(columnDefinition = "varchar(10)")
    private String unit;

    /**
     * 商品Logo
     */
    @Column(columnDefinition = "varchar(400)")
    private String logo;

    /**
     * 商品原价（B2B、SRM订单原价=单价）
     */
    @Column(columnDefinition = "numeric(15,3)")
    private BigDecimal originalPrice;

    /**
     * 商品单价（订单价）
     */
    @Column(columnDefinition = "numeric(15,3)")
    private BigDecimal price;

    /**
     * 商品到手价（营销活动订单有此价格，默认等于单价）
     */
    @Column(columnDefinition = "numeric(15,3)")
    private BigDecimal refPrice;

    /**
     * 供应商库存
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal stock;

    /**
     * 会员折扣
     */
    @Column(columnDefinition = "numeric(8,4)")
    private BigDecimal discount;

    /**
     * 采购数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal quantity;

    /**
     * 是否含税
     */
    @Column
    private Boolean tax;

    /**
     * 税率（百分比转换的小数）
     */
    @Column(columnDefinition = "numeric(8,4)")
    private BigDecimal taxRate;

    /**
     * 金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal amount;

    /**
     * 使用“平台优惠券”后的抵扣优惠金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal platformCouponAmount;

    /**
     * 已经支付的金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal paidAmount;

    /**
     * 配送方式，定义在 OrderProductDeliverTypeEnum 中，1.物流 2.自提 3.无需配送 4.物流+自提
     */
    @Column
    private Integer deliverType;

    /**
     * 运费方式，定义在 OrderFreightTypeEnum 中， 0-无运费方式，1-卖家承担，2-买家承担
     */
    @Column
    private Integer freightType;

    /**
     * 商品重量
     */
    @Column(columnDefinition = "numeric(15,3)")
    private BigDecimal weight;

    /**
     * 运费模板Id
     */
    @Column
    private Long logisticsTemplateId;

    /**
     * 已发货数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal delivered;

    /**
     * 已收货的数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal received;

    /**
     * 已通知送货的数量
     */
    @Column(columnDefinition = "numeric(15,4) default 0")
    private BigDecimal noticeCount;

    /**
     * 未发货的数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal leftCount;

    /**
     * 差异数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal differCount;

    /**
     * 换货数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal exchangeCount;

    /**
     * 退货数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal returnCount;

    /**
     * 维修数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal maintainCount;

    /**
     * 退款金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal returnAmount;

    /**
     * 0418新增：实际退款金额
     */
    @Column(columnDefinition = "numeric")
    private BigDecimal refReturnAmount;

    /**
     * 加工数量
     */
    @Column(columnDefinition = "numeric(15,4)")
    private BigDecimal enhanceCount;

    /**
     * 自提地址（如配送方式为自提，必填）
     */
    @Column(columnDefinition = "varchar(200)")
    private String address;

    /**
     * 接收人（如配送方式为自提，必填）
     */
    @Column(columnDefinition = "varchar(50)")
    private String receiver;

    /**
     * 接收人电话（如配送方式为自提，必填）
     */
    @Column(columnDefinition = "varchar(20)")
    private String phone;

    /**
     * 合并下单、拆单类型枚举，定义在 OrderSeparateTypeEnum 中
     */
    @Column
    private Integer separateType;

    /**
     * （转单订单、转单后的订单）上级、下级订单商品的Id（OrderProductDO的Id）
     */
    @Column
    private Long relationId;

    /**
     * 一对多双向关联营销活动
     */
    @JsonManagedReference
    @OneToMany(mappedBy = "product", cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.LAZY)
    private Set<OrderPromotionDO> promotions;

    /**
     * 一对一双向关联订单物料关联的商品信息
     */
    @JsonManagedReference
    @OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE}, fetch = FetchType.EAGER)
    @JoinColumn(name="material_id", referencedColumnName="id")
    private OrderMaterialDO material;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public BigDecimal getNoticeCount() {
        return noticeCount;
    }

    public void setNoticeCount(BigDecimal noticeCount) {
        this.noticeCount = noticeCount;
    }

    public OrderDO getOrder() {
        return order;
    }

    public void setOrder(OrderDO order) {
        this.order = order;
    }

    public Integer getPriceType() {
        return priceType;
    }

    public void setPriceType(Integer priceType) {
        this.priceType = priceType;
    }

    public Long getProductId() {
        return productId;
    }

    public void setProductId(Long productId) {
        this.productId = productId;
    }

    public Long getSkuId() {
        return skuId;
    }

    public void setSkuId(Long skuId) {
        this.skuId = skuId;
    }

    public Long getStockId() {
        return stockId;
    }

    public void setStockId(Long stockId) {
        this.stockId = stockId;
    }

    public Long getCartId() {
        return cartId;
    }

    public void setCartId(Long cartId) {
        this.cartId = cartId;
    }

    public String getProductNo() {
        return productNo;
    }

    public void setProductNo(String productNo) {
        this.productNo = productNo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getSpec() {
        return spec;
    }

    public void setSpec(String spec) {
        this.spec = spec;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public String getLogo() {
        return logo;
    }

    public void setLogo(String logo) {
        this.logo = logo;
    }

    public BigDecimal getOriginalPrice() {
        return originalPrice;
    }

    public void setOriginalPrice(BigDecimal originalPrice) {
        this.originalPrice = originalPrice;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getRefPrice() {
        return refPrice;
    }

    public void setRefPrice(BigDecimal refPrice) {
        this.refPrice = refPrice;
    }

    public BigDecimal getStock() {
        return stock;
    }

    public void setStock(BigDecimal stock) {
        this.stock = stock;
    }

    public BigDecimal getDiscount() {
        return discount;
    }

    public void setDiscount(BigDecimal discount) {
        this.discount = discount;
    }

    public BigDecimal getQuantity() {
        return quantity;
    }

    public void setQuantity(BigDecimal quantity) {
        this.quantity = quantity;
    }

    public Boolean getTax() {
        return tax;
    }

    public void setTax(Boolean tax) {
        this.tax = tax;
    }

    public BigDecimal getTaxRate() {
        return taxRate;
    }

    public void setTaxRate(BigDecimal taxRate) {
        this.taxRate = taxRate;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public BigDecimal getPlatformCouponAmount() {
        return platformCouponAmount;
    }

    public void setPlatformCouponAmount(BigDecimal platformCouponAmount) {
        this.platformCouponAmount = platformCouponAmount;
    }

    public BigDecimal getPaidAmount() {
        return paidAmount;
    }

    public void setPaidAmount(BigDecimal paidAmount) {
        this.paidAmount = paidAmount;
    }

    public Integer getDeliverType() {
        return deliverType;
    }

    public void setDeliverType(Integer deliverType) {
        this.deliverType = deliverType;
    }

    public Integer getFreightType() {
        return freightType;
    }

    public void setFreightType(Integer freightType) {
        this.freightType = freightType;
    }

    public BigDecimal getWeight() {
        return weight;
    }

    public void setWeight(BigDecimal weight) {
        this.weight = weight;
    }

    public Long getLogisticsTemplateId() {
        return logisticsTemplateId;
    }

    public void setLogisticsTemplateId(Long logisticsTemplateId) {
        this.logisticsTemplateId = logisticsTemplateId;
    }

    public BigDecimal getDelivered() {
        return delivered;
    }

    public void setDelivered(BigDecimal delivered) {
        this.delivered = delivered;
    }

    public BigDecimal getReceived() {
        return received;
    }

    public void setReceived(BigDecimal received) {
        this.received = received;
    }

    public BigDecimal getLeftCount() {
        return leftCount;
    }

    public void setLeftCount(BigDecimal leftCount) {
        this.leftCount = leftCount;
    }

    public BigDecimal getDifferCount() {
        return differCount;
    }

    public void setDifferCount(BigDecimal differCount) {
        this.differCount = differCount;
    }

    public BigDecimal getExchangeCount() {
        return exchangeCount;
    }

    public void setExchangeCount(BigDecimal exchangeCount) {
        this.exchangeCount = exchangeCount;
    }

    public BigDecimal getReturnCount() {
        return returnCount;
    }

    public void setReturnCount(BigDecimal returnCount) {
        this.returnCount = returnCount;
    }

    public BigDecimal getMaintainCount() {
        return maintainCount;
    }

    public void setMaintainCount(BigDecimal maintainCount) {
        this.maintainCount = maintainCount;
    }

    public BigDecimal getReturnAmount() {
        return returnAmount;
    }

    public void setReturnAmount(BigDecimal returnAmount) {
        this.returnAmount = returnAmount;
    }

    public BigDecimal getEnhanceCount() {
        return enhanceCount;
    }

    public void setEnhanceCount(BigDecimal enhanceCount) {
        this.enhanceCount = enhanceCount;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getReceiver() {
        return receiver;
    }

    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Integer getSeparateType() {
        return separateType;
    }

    public void setSeparateType(Integer separateType) {
        this.separateType = separateType;
    }

    public Long getRelationId() {
        return relationId;
    }

    public void setRelationId(Long relationId) {
        this.relationId = relationId;
    }

    public Set<OrderPromotionDO> getPromotions() {
        return promotions;
    }

    public void setPromotions(Set<OrderPromotionDO> promotions) {
        this.promotions = promotions;
    }

    public OrderMaterialDO getMaterial() {
        return material;
    }

    public void setMaterial(OrderMaterialDO material) {
        this.material = material;
    }

    public BigDecimal getRefReturnAmount() {
        return refReturnAmount;
    }

    public void setRefReturnAmount(BigDecimal refReturnAmount) {
        this.refReturnAmount = refReturnAmount;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        OrderProductDO orderProductDO = (OrderProductDO) o;
        return id.equals(orderProductDO.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}
